from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import List, Optional

from database import get_db
from models import DictType, DictItem
from schemas.dict import (
    DictTypeCreate, DictTypeUpdate, DictTypeSchema, DictTypeWithItems,
    DictItemCreate, DictItemUpdate, DictItemSchema
)
from api.deps import get_current_active_user
from models.user import User

router = APIRouter()

# ===================== 字典类型相关接口 =====================

@router.get("/types", response_model=List[DictTypeSchema], tags=["数据字典"])
async def get_dict_types(
    skip: int = Query(0, ge=0, description="跳过的记录数"),
    limit: int = Query(100, ge=1, le=1000, description="返回的记录数"),
    is_active: Optional[bool] = Query(None, description="是否激活"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """获取字典类型列表"""
    query = db.query(DictType)
    if is_active is not None:
        query = query.filter(DictType.is_active == is_active)
    types = query.order_by(DictType.sort_order, DictType.id).offset(skip).limit(limit).all()
    return types

@router.get("/types/{dict_type_id}", response_model=DictTypeWithItems, tags=["数据字典"])
async def get_dict_type(
    dict_type_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """获取字典类型详情（包含字典项）"""
    dict_type = db.query(DictType).filter(DictType.id == dict_type_id).first()
    if not dict_type:
        raise HTTPException(status_code=404, detail="字典类型不存在")
    return dict_type

@router.post("/types", response_model=DictTypeSchema, status_code=201, tags=["数据字典"])
async def create_dict_type(
    dict_type_in: DictTypeCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """创建字典类型（仅超级管理员可操作）"""
    # 检查名称是否已存在
    if db.query(DictType).filter(DictType.name == dict_type_in.name).first():
        raise HTTPException(status_code=400, detail="字典类型名称已存在")
    # 检查编码是否已存在
    if db.query(DictType).filter(DictType.code == dict_type_in.code).first():
        raise HTTPException(status_code=400, detail="字典类型编码已存在")
    
    dict_type = DictType(**dict_type_in.model_dump())
    db.add(dict_type)
    db.commit()
    db.refresh(dict_type)
    return dict_type

@router.put("/types/{dict_type_id}", response_model=DictTypeSchema, tags=["数据字典"])
async def update_dict_type(
    dict_type_id: int,
    dict_type_in: DictTypeUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """更新字典类型（仅超级管理员可操作）"""
    dict_type = db.query(DictType).filter(DictType.id == dict_type_id).first()
    if not dict_type:
        raise HTTPException(status_code=404, detail="字典类型不存在")
    
    # 检查名称是否已被其他记录使用
    if dict_type_in.name and dict_type_in.name != dict_type.name:
        if db.query(DictType).filter(DictType.name == dict_type_in.name, DictType.id != dict_type_id).first():
            raise HTTPException(status_code=400, detail="字典类型名称已存在")
    
    # 检查编码是否已被其他记录使用
    if dict_type_in.code and dict_type_in.code != dict_type.code:
        if db.query(DictType).filter(DictType.code == dict_type_in.code, DictType.id != dict_type_id).first():
            raise HTTPException(status_code=400, detail="字典类型编码已存在")
    
    update_data = dict_type_in.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(dict_type, field, value)
    
    db.commit()
    db.refresh(dict_type)
    return dict_type

@router.delete("/types/{dict_type_id}", status_code=204, tags=["数据字典"])
async def delete_dict_type(
    dict_type_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """删除字典类型（仅超级管理员可操作）"""
    dict_type = db.query(DictType).filter(DictType.id == dict_type_id).first()
    if not dict_type:
        raise HTTPException(status_code=404, detail="字典类型不存在")
    
    db.delete(dict_type)
    db.commit()
    return None

# ===================== 字典项相关接口 =====================

@router.get("/items", response_model=List[DictItemSchema], tags=["数据字典"])
async def get_dict_items(
    dict_type_id: Optional[int] = Query(None, description="字典类型ID"),
    is_active: Optional[bool] = Query(True, description="是否激活"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """获取字典项列表"""
    query = db.query(DictItem)
    if dict_type_id is not None:
        query = query.filter(DictItem.dict_type_id == dict_type_id)
    if is_active is not None:
        query = query.filter(DictItem.is_active == is_active)
    items = query.order_by(DictItem.sort_order, DictItem.id).all()
    return items

@router.get("/items/{dict_item_id}", response_model=DictItemSchema, tags=["数据字典"])
async def get_dict_item(
    dict_item_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """获取字典项详情"""
    dict_item = db.query(DictItem).filter(DictItem.id == dict_item_id).first()
    if not dict_item:
        raise HTTPException(status_code=404, detail="字典项不存在")
    return dict_item

@router.post("/items", response_model=DictItemSchema, status_code=201, tags=["数据字典"])
async def create_dict_item(
    dict_item_in: DictItemCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """创建字典项（仅超级管理员可操作）"""
    # 检查字典类型是否存在
    dict_type = db.query(DictType).filter(DictType.id == dict_item_in.dict_type_id).first()
    if not dict_type:
        raise HTTPException(status_code=404, detail="字典类型不存在")
    
    # 检查同一字典类型下值是否重复
    if db.query(DictItem).filter(
        DictItem.dict_type_id == dict_item_in.dict_type_id,
        DictItem.value == dict_item_in.value
    ).first():
        raise HTTPException(status_code=400, detail="同一字典类型下值不能重复")
    
    dict_item = DictItem(**dict_item_in.model_dump())
    db.add(dict_item)
    db.commit()
    db.refresh(dict_item)
    return dict_item

@router.put("/items/{dict_item_id}", response_model=DictItemSchema, tags=["数据字典"])
async def update_dict_item(
    dict_item_id: int,
    dict_item_in: DictItemUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """更新字典项（仅超级管理员可操作）"""
    dict_item = db.query(DictItem).filter(DictItem.id == dict_item_id).first()
    if not dict_item:
        raise HTTPException(status_code=404, detail="字典项不存在")
    
    # 如果更新值，检查是否重复
    if dict_item_in.value and dict_item_in.value != dict_item.value:
        if db.query(DictItem).filter(
            DictItem.dict_type_id == dict_item.dict_type_id,
            DictItem.value == dict_item_in.value,
            DictItem.id != dict_item_id
        ).first():
            raise HTTPException(status_code=400, detail="同一字典类型下值不能重复")
    
    update_data = dict_item_in.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(dict_item, field, value)
    
    db.commit()
    db.refresh(dict_item)
    return dict_item

@router.delete("/items/{dict_item_id}", status_code=204, tags=["数据字典"])
async def delete_dict_item(
    dict_item_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """删除字典项（仅超级管理员可操作）"""
    dict_item = db.query(DictItem).filter(DictItem.id == dict_item_id).first()
    if not dict_item:
        raise HTTPException(status_code=404, detail="字典项不存在")
    
    db.delete(dict_item)
    db.commit()
    return None

# ===================== 业务接口 =====================

@router.get("/by-code/{code}", response_model=List[DictItemSchema], tags=["数据字典"])
async def get_dict_items_by_code(
    code: str,
    is_active: bool = Query(True, description="是否激活"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user)
):
    """根据字典编码获取字典项列表（业务接口，方便前端使用）"""
    dict_type = db.query(DictType).filter(DictType.code == code).first()
    if not dict_type:
        raise HTTPException(status_code=404, detail=f"字典编码 {code} 不存在")
    
    items = db.query(DictItem).filter(
        DictItem.dict_type_id == dict_type.id,
        DictItem.is_active == is_active
    ).order_by(DictItem.sort_order, DictItem.id).all()
    
    return items